#ifndef APPLICATION_H_
#define APPLICATION_H_

#include "conf.h"
#include "yellowpage.h"
#include "menu.h"
#include "keybind.h"
#include "icon.h"
#include "misc.h"

namespace gpyp {

class OptionContext;
class PrefDialog;
class Process;
typedef boost::shared_ptr<Process> RefProcess;
class CommandRunner;
class MainWindow;
typedef boost::shared_ptr<MainWindow> RefMainWindow;
class FavoriteCollection;
typedef boost::shared_ptr<FavoriteCollection> RefFavoriteCollection;

class Application : boost::noncopyable {
private:
  sigc::signal<void, RefChannel> signal_channel_selected_;
public:
  inline sigc::signal<void, RefChannel> signal_channel_selected() {
    return signal_channel_selected_;
  }

public:
  typedef std::list<ConfMenu::RefMenu> MenuList;

private:
  conf::RefAttributeBool auto_play_;

  OptionContext        &opts_;
  BuiltinCommand       *bc_root_;
  Conf                 *conf_;
  IconManager           iconmanager_;
  CommandRunner        *commandrunner_;
  RefYPCollection       ypcollection_;
  RefFavoriteCollection favcollection_;

  RefMainWindow     mainwindow_;

  Glib::ThreadPool *thread_pool_;

  BuiltinCommand   &bc_config_;
  BuiltinCommand   &bc_debug_;

  void on_channel_selected();

  void ypcollection_on_loaded();
  void ypcollection_on_error(YellowPage &yp);

  void commandrunner_process_on_aborted(RefProcess proc);

  void menu_yp_on_load_default(ConfMenu::Menu &menu);
  void menu_ch_on_load_default(ConfMenu::Menu &menu);
  void menu_tool_on_load_default(ConfMenu::Menu &menu);
  void menu_text_on_load_default(ConfMenu::Menu &menu);
  void menu_proc_on_load_default(ConfMenu::Menu &menu);
  void menu_pc_relay_on_load_default(ConfMenu::Menu &menu);
  void menu_pc_connection_on_load_default(ConfMenu::Menu &menu);
  void menu_webview_on_load_default(ConfMenu::Menu &menu);

  void key_mainwindow_on_load_default(KeyBind &keybind);
  void key_channellist_on_load_default(KeyBind &keybind);
  void key_text_editor_on_load_default(KeyBind &keybind);
  void key_search_on_load_default(KeyBind &keybind);
  void key_searchbar_on_load_default(KeyBind &keybind);
  void key_webview_on_load_default(KeyBind &keybind);

public:
  inline conf::RefAttributeBool auto_play() {
    return auto_play_;
  }

  int main(Gtk::Main &kit);

  inline OptionContext &opts() {
    return opts_;
  }
  inline BuiltinCommand &bc() {
    return *bc_root_;
  }
  inline Conf &conf() {
    return *conf_;
  }
  inline CommandRunner &commandrunner() {
    return *commandrunner_;
  }
  inline RefYPCollection ypcollection() {
    return ypcollection_;
  }
  inline RefFavoriteCollection favcollection() {
    return favcollection_;
  }

  inline RefMainWindow mainwindow() {
    return mainwindow_;
  }
  RefChannel get_selected_channel();

  inline void thread(const sigc::slot<void> &slot) {
    thread_pool_->push(slot);
  }

private:
  bool bc_config_save(ShellLine &line, CommandOpts &opts);
  bool bc_config_view(ShellLine &line, CommandOpts &opts);
  bool bc_debug_g_mem_profile(ShellLine &line, CommandOpts &opts);

public:
  Application(OptionContext &opts);
  virtual ~Application();
};

}/*gpyp*/

#endif/*APPLICATION_H_*/
